<template>
  <div class="cropper-wrapper">
    <el-card class="cropper-card">
      <div class="img-box">
        <cropper-canvas ref="croppedCanvas" :scaleStep="0.1" background style="height: 420px">
          <cropper-image
            ref="cropperImage"
            :src="insideSrc"
            alt="Picture"
            rotatable
            scalable
            skewable
            translatable />
          <cropper-shade hidden />
          <cropper-handle ref="croppedCanvasHandle" action="move" plain />
          <cropper-selection
            ref="cropperSelection"
            initial-coverage="0.5"
            @change="changeSelection"
            movable
            zoomable
            keyboard
            resizable
            outlined>
            <cropper-handle
              ref="croppedSelectionHandle"
              action="move"
              theme-color="rgba(255, 255, 255, 0.35)" />
            <cropper-handle action="n-resize" />
            <cropper-handle action="e-resize" />
            <cropper-handle action="s-resize" />
            <cropper-handle action="w-resize" />
            <cropper-handle action="ne-resize" />
            <cropper-handle action="nw-resize" />
            <cropper-handle action="se-resize" />
            <cropper-handle action="sw-resize" />
          </cropper-selection>
        </cropper-canvas>
      </div>
      <div class="right-con">
        <el-row style="height: 185px">
          <div class="preview-box preview-lg">
            <cropper-viewer selection="cropper-selection" class="img-preview" />
          </div>
        </el-row>
        <el-row style="height: 170px">
          <div class="preview-box preview-md">
            <cropper-viewer selection="cropper-selection" class="img-preview" />
          </div>
          <div class="preview-box preview-sm">
            <cropper-viewer selection="cropper-selection" class="img-preview" />
          </div>
          <div class="preview-box preview-xs">
            <cropper-viewer selection="cropper-selection" class="img-preview" />
          </div>
        </el-row>
        <el-row style="margin-top: 33px; display: inline-block">
          <div style="float: left">
            <el-upload :before-upload="beforeUpload" action="image/upload">
              <el-button size="small" style="width: 150px" type="primary">
                {{ $t('forms.buttons.upload') }}
              </el-button>
            </el-upload>
          </div>
          <div style="float: left; margin-left: 20px">
            <el-button
              v-show="insideSrc"
              size="small"
              style="width: 150px"
              type="primary"
              @click="crop">
              {{ cropButtonText }}
            </el-button>
          </div>
        </el-row>
      </div>
      <div class="input-box">
        <el-row :gutter="16">
          <el-col :span="6">
            <el-input v-model="X" size="small" @blur="reSize" @keyup.enter="reSize" type="number">
              <template #prepend>X</template>
              <template #append>px</template>
            </el-input>
          </el-col>
          <el-col :span="6">
            <el-input
              v-model="Y"
              size="small"
              @on-blur="reSize"
              @keyup.enter="reSize"
              type="number">
              <template #prepend>Y</template>
              <template #append>px</template>
            </el-input>
          </el-col>
          <el-col :span="6">
            <el-input
              v-model="width"
              size="small"
              @on-blur="reSize"
              @keyup.enter="reSize"
              type="number">
              <template #prepend>{{ $t('forms.width') }}</template>
              <template #append>px</template>
            </el-input>
          </el-col>
          <el-col :span="6">
            <el-input
              v-model="height"
              size="small"
              @on-blur="reSize"
              @keyup.enter="reSize"
              type="number">
              <template #prepend>{{ $t('forms.height') }}</template>
              <template #append>px</template>
            </el-input>
          </el-col>
        </el-row>
      </div>
      <div class="button-box">
        <el-button-group style="margin-right: 10px">
          <el-button size="small" type="primary" @click="reset">
            <el-icon>
              <el-icon-refresh />
            </el-icon>
          </el-button>
          <el-button size="small" type="primary" @click="mode('move')">
            <el-icon>
              <el-icon-rank />
            </el-icon>
          </el-button>
          <el-button size="small" type="primary" @click="mode('select')">
            <el-icon>
              <el-icon-crop />
            </el-icon>
          </el-button>
        </el-button-group>
        <el-button-group style="margin-right: 10px">
          <el-button size="small" type="primary" @click="zoom(-0.1)">
            <el-icon>
              <el-icon-zoom-out />
            </el-icon>
          </el-button>
          <el-button size="small" type="primary" @click="zoom(0.1)">
            <el-icon>
              <el-icon-zoom-in />
            </el-icon>
          </el-button>
        </el-button-group>
        <el-button-group style="margin-right: 10px">
          <el-button size="small" type="primary" @click="rotate(-1)">
            <el-icon>
              <el-icon-refresh-left />
            </el-icon>
          </el-button>
          <el-button size="small" type="primary" @click="rotate(1)">
            <el-icon>
              <el-icon-refresh-right />
            </el-icon>
          </el-button>
          <el-button size="small" type="primary" @click="scale('X')">
            <el-icon style="transform: rotate(90deg)">
              <el-icon-d-caret />
            </el-icon>
          </el-button>
          <el-button size="small" type="primary" @click="scale('Y')">
            <el-icon>
              <el-icon-d-caret />
            </el-icon>
          </el-button>
        </el-button-group>
        <el-button-group style="margin-right: 10px">
          <el-button size="small" type="primary" @click="move(0, -1)">
            <el-icon>
              <el-icon-caret-top />
            </el-icon>
          </el-button>
          <el-button size="small" type="primary" @click="move(-1, 0)">
            <el-icon>
              <el-icon-caret-left />
            </el-icon>
          </el-button>
          <el-button size="small" type="primary" @click="move(0, 1)">
            <el-icon>
              <el-icon-caret-bottom />
            </el-icon>
          </el-button>
          <el-button size="small" type="primary" @click="move(1, 0)">
            <el-icon>
              <el-icon-caret-right />
            </el-icon>
          </el-button>
        </el-button-group>
        <el-button-group>
          <el-button size="small" type="primary" @click="aspact(16 / 9)">16:9</el-button>
          <el-button size="small" type="primary" @click="aspact(4 / 3)">4:3</el-button>
          <el-button size="small" type="primary" @click="aspact(1)">1:1</el-button>
          <el-button size="small" type="primary" @click="aspact(2 / 3)">2:3</el-button>
          <el-button size="small" type="primary" @click="aspact(NaN)"
            >{{ $t('forms.buttons.free') }}
          </el-button>
        </el-button-group>
      </div>
    </el-card>
  </div>
</template>

<script>
import avatarImg from '@/assets/images/avatar/avatar.jpg'
import { nextTick, ref } from 'vue'
import 'cropperjs'
import './index.less'

export default {
  name: 'Cropper',
  props: {
    src: {
      type: String,
      default: ''
    },
    cropButtonText: String
  },
  data() {
    return {
      insideSrc: avatarImg,
      X: 0,
      Y: 0,
      width: 0,
      height: 0
    }
  },
  watch: {
    src(src) {
      nextTick(() => {
        this.insideSrc = src
        this.reset()
      })
    }
  },
  methods: {
    beforeUpload(file) {
      const reader = new FileReader()
      reader.readAsDataURL(file)
      reader.onload = (event) => {
        this.insideSrc = event.target.result
      }
      return false
    },
    reset() {
      this.width = 250
      this.height = 250
      this.reSize()
      this.cropperSelection.$center()
    },
    mode(value) {
      this.croppedCanvasHandle.action = value
      this.croppedSelectionHandle.action = value
    },
    rotate(value) {
      if (value > 0) {
        this.cropperImage.$rotate(Math.PI / 2)
      } else {
        this.cropperImage.$rotate(-Math.PI / 2)
      }
    },
    zoom(value) {
      this.cropperImage.$zoom(value)
    },
    scale(d) {
      if (d === 'X') {
        this.cropperImage.$scale(-1, 1)
      } else {
        this.cropperImage.$scale(1, -1)
      }
    },
    move(...args) {
      this.cropperSelection.$move(...args)
    },
    aspact(value) {
      this.cropperSelection.aspectRatio = value
    },
    reSize() {
      this.cropperSelection.$change(
        Number(this.X),
        Number(this.Y),
        Number(this.width),
        Number(this.height)
      )
    },
    crop() {
      this.cropperSelection.$toCanvas().then((canvas) => {
        this.$emit('on-crop', canvas.toDataURL())
      })
    },
    changeSelection(event) {
      this.X = event.detail.x
      this.Y = event.detail.y
      this.width = event.detail.width
      this.height = event.detail.height
    }
  },
  setup() {
    const croppedCanvas = ref(null)
    const cropperImage = ref(null)
    const cropperSelection = ref(null)
    const croppedCanvasHandle = ref(null)
    const croppedSelectionHandle = ref(null)
    return {
      croppedCanvas,
      cropperImage,
      cropperSelection,
      croppedCanvasHandle,
      croppedSelectionHandle
    }
  }
}
</script>
